home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / TCL1 / JOHNLOVE / C_SOURCE / CMYDOC.C < prev    next >
Text File  |  1992-01-17  |  13KB  |  433 lines

  1. /*********************************************************
  2.  "CmyDoc.c"
  3.  
  4.  by John A. Love, III [Washington Apple Pi Users' Group]
  5.  
  6.  using Symantec's "THINK C", v 5.0.1
  7.  ... as derived from their "TCL Starter" files
  8.  *********************************************************/
  9.  
  10.  
  11.  
  12.  
  13. #include <Commands.h>
  14. #include <CApplication.h>
  15. #include <CBartender.h>
  16. #include <CDataFile.h>
  17. #include <CDecorator.h>
  18. #include <CDesktop.h>
  19. #include <CError.h>
  20. #include <CPanorama.h>
  21. #include <CScrollPane.h>
  22. #include <TBUtilities.h>
  23. #include <CWindow.h>
  24. #include <Packages.h>
  25.  
  26. #include "CmyGlobals.h"
  27. #include "CmyDoc.h"
  28. #include "CmyPane.h"
  29.  
  30.  
  31. #define    WINDStarter        500        /* Resource ID for WIND template */
  32.  
  33.  
  34. extern    CApplication    *gApplication;    /* The application */
  35. extern    CBartender        *gBartender;    /* The menu handling object */
  36. extern    CDecorator        *gDecorator;    /* Window dressing object    */
  37. extern    CDesktop        *gDesktop;        /* The enclosure for all windows */
  38. extern    CBureaucrat        *gGopher;        /* The current boss in the chain of command */
  39. extern    OSType            gSignature;        /* The application's signature */
  40. extern    CError            *gError;        /* The global error handler */
  41.  
  42.  
  43.  
  44. void    CStarterDoc::IStarterDoc (CApplication *aSupervisor, Boolean printable)        {
  45.  
  46.  
  47.     CDocument::IDocument(aSupervisor, printable);
  48.     
  49. }    /* IStarterDoc */
  50.  
  51.  
  52.  
  53. /* Dispose
  54. **
  55. **        This is your document's destruction method.
  56. **        If you allocated memory in your initialization method
  57. **        or opened temporary files, this is the place to release them.
  58. **
  59. **        Be sure to call the default method!
  60. */
  61.  
  62. void    CStarterDoc::Dispose (void)        {
  63.  
  64.  
  65.     inherited::Dispose();
  66.     
  67. }    /* Dispose */
  68.  
  69.  
  70.  
  71. /* DoCommand
  72. **
  73. **        This is the heart of your document.
  74. **        In this method, you handle all the commands your document deals with.
  75. **
  76. **        Be sure to call the default method to handle the standard
  77. **        document commands: cmdClose, cmdSave, cmdSaveAs, cmdRevert,
  78. **        cmdPageSetup, cmdPrint, and cmdUndo. To change the way these
  79. **        commands are handled, override the appropriate methods instead
  80. **        of handling them here.
  81. */
  82.  
  83. void    CStarterDoc::DoCommand (long theCommand)    {
  84.  
  85.  
  86.     switch (theCommand) {
  87.  
  88.         // your document commands here:
  89.     
  90.         default:
  91.             inherited::DoCommand(theCommand);
  92.             break;
  93.     }
  94.     
  95. }    /* DoCommand */
  96.  
  97.  
  98.  
  99. /* UpdateMenus
  100. **
  101. **      In this method you can enable menu commands that apply when
  102. **      your document is active.
  103. **
  104. **      Be sure to call the inherited method to get the default behavior.
  105. **      The inherited method enables these commands: cmdClose, cmdSaveAs,
  106. **      cmdSave, cmdRevert, cmdPageSetup, cmdPrint, cmdUndo.
  107. */
  108.  
  109. void    CStarterDoc::UpdateMenus (void)        {
  110.  
  111.  
  112.   inherited::UpdateMenus();
  113.  
  114.     /* Enable your menu commands here (enable each one with a call to   
  115.        gBartender->EnableCmd(command_number)).                          */                      
  116.  
  117. }    /* UpdateMenus */
  118.  
  119.  
  120.  
  121. /* NewFile
  122. **
  123. **        When the user chooses New from the File menu, the CreateDocument()
  124. **        method in your Application class will send a newly created document
  125. **        this message. This method needs to create a new window, ready to
  126. **        work on a new document.
  127. **
  128. **        Since this method and the OpenFile() method share the code for creating
  129. **        the window, you should use an auxiliary window-building method.
  130. */
  131.  
  132. void    CStarterDoc::NewFile (void)        {
  133.  
  134.         Str255  wTitle;        /* Window title string.         */
  135.         short   wCount;        /* Index number of new window.  */
  136.         Str255  wNumber;    /* Index number as a string.    */
  137.     
  138.     
  139.     /* BuildWindow() is the method that does the work of creating a window.
  140.     ** Its parameter should be the data that you want to display in the window.
  141.     ** Since this is a new window, there's nothing to display.                    */
  142.  
  143.     BuildWindow(NULL);
  144.     
  145.     // Append an index number to the default name of the window:
  146.          
  147.     itsWindow->GetTitle(wTitle);
  148.     wCount = gDecorator->GetWCount();
  149.     NumToString(wCount, wNumber);
  150.     ConcatPStrings(wTitle, (StringPtr) "\p ");
  151.     ConcatPStrings(wTitle, wNumber);
  152.     itsWindow->SetTitle(wTitle);
  153.  
  154.     // Send the window a Select() message to make it the active window:
  155.     
  156.     itsWindow->Select();
  157.     
  158. }    /* NewFile */
  159.  
  160.  
  161.  
  162. /* OpenFile
  163. **
  164. **        When the user chooses Open╔ from the File menu, the OpenDocument()
  165. **        method in your Application class will let the user choose a file
  166. **        and then send a newly created document this message. The information
  167. **        about the file is in the SFReply record.
  168. **
  169. **        In this method, you need to open the file and display its contents
  170. **        in a window. This method uses the auxiliary window-building method.
  171. */
  172.  
  173. void    CStarterDoc::OpenFile (SFReply *macSFReply)        {
  174.  
  175.         CDataFile    *theFile;
  176.         Handle        theData = NULL;
  177.         Str63        theName;
  178.         OSErr        theError;
  179.     
  180.     
  181.     TRY
  182.     {
  183.     
  184.             /* Create a file and send it a SFSpecify()
  185.             ** message to set up the name, volume, and directory. */
  186.     
  187.         theFile = new(CDataFile);
  188.         theFile->IDataFile();
  189.         theFile->SFSpecify(macSFReply);
  190.         
  191.             /* Be sure to set the instance variable
  192.             ** so other methods can use the file if they
  193.             ** need to. This is especially important if
  194.             ** you leave the file open in this method.
  195.             ** If you close the file after reading it, you
  196.             ** should be sure to set itsFile to NULL.        */
  197.     
  198.         itsFile = theFile;
  199.     
  200.             /* Send the file an Open() message to open it. You can use the
  201.             ** ReadSome() or ReadAll() methods to get the contents of the file.    */
  202.     
  203.         theFile->Open(fsRdWrPerm);
  204.         
  205.             /* Make sure that the memory request to read the data from
  206.             ** the file doesn't use up any of our rainy day fund and
  207.             ** that the GrowMemory() method (in the application) knows
  208.             ** that it's OK if we couldn't get enough memory.            */
  209.     
  210.     
  211.         theData = theFile->ReadAll();     /* ReadAll() creates the handle */
  212.         
  213.         BuildWindow(theData);
  214.     
  215.             /* In your application, you'll probably store the data in
  216.             ** some form as an instance variable in your document class.
  217.             ** For this example, there's no need to save it, so get rid of it. */
  218.     
  219.         DisposHandle(theData);
  220.         theData = NULL;
  221.     
  222.             /* In this implementation, we leave the file open. You might
  223.             ** want to close it after you've read in all the data.        */
  224.     
  225.         itsFile->GetName(theName);
  226.         itsWindow->SetTitle(theName);
  227.         itsWindow->Select();            // Don't forget to make the window active.
  228.     }
  229.     
  230.     CATCH
  231.     {
  232.         /* This exception handler will be executed if an exception occurs
  233.         ** anywhere within the scope of the TRY block above.
  234.         ** You should perform any cleanup of things that won't be needed
  235.         ** since the document could not be opened. By convention,
  236.         ** the creator of an object is responsible for sending it
  237.         ** the Dispose message. This means that we should only dispose
  238.         ** of things that would not be taken care of in Dispose.
  239.         ** In this case, we just make sure that the Handle theData
  240.         ** has been disposed of. The exception will propagate up to
  241.         ** CApplications's exception handler, which handles displaying
  242.         ** an error alert.                                                */
  243.          
  244.          if (theData) DisposHandle( theData);
  245.          
  246.     }
  247.     
  248.     ENDTRY;
  249.     
  250. }    /* OpenFile */
  251.  
  252.  
  253.  
  254. /* BuildWindow
  255. **
  256. **        This is the auxiliary window-building method that the
  257. **        NewFile() and OpenFile() methods use to create a window.
  258. **
  259. **        In this implementation, the argument is the data to display.
  260. */
  261.  
  262. void    CStarterDoc::BuildWindow (Handle theData)    {
  263.  
  264.         CScrollPane        *theScrollPane;
  265.         CStarterPane    *theMainPane;
  266.  
  267.  
  268.         /* First create the window and initialize it. The first argument
  269.         ** is the resource ID of the window. The second argument specifies
  270.         ** whether the window is a floating window.  The third argument is
  271.         ** the window's enclosure; it should always be gDesktop. The last
  272.         ** argument is the window's supervisor in the Chain of Command;
  273.         ** it should always be the Document object.                            */
  274.  
  275.     itsWindow = new(CWindow);
  276.     itsWindow->IWindow(WINDStarter, FALSE, gDesktop, this);
  277.     
  278.         /* After you create the window, you can use the SetSizeRect() message
  279.         ** to set the window╒s maximum and minimum size. Be sure to set the
  280.         ** max & min BEFORE you send a PlaceNewWindow() message to the decorator.
  281.         **
  282.         ** The default minimum is 100 by 100 pixels. The default maximum is the
  283.         ** bounds of GrayRgn()  We'll use the defaults.                            */
  284.     
  285.         /* Our window will contain a ScrollPane, which in turn will contain
  286.         ** a Panorama.  Now, let's create the ScrollPane.                    */
  287.  
  288.     theScrollPane = new(CScrollPane);
  289.     
  290.         /* You can initialize a scroll pane two ways:
  291.         **        1. You can specify all the values
  292.         **           right in your code, like this.
  293.         **        2. You can create a ScPn resource and
  294.         **           initialize the pane from the information
  295.         **           in the resource.
  296.         */
  297.  
  298.     theScrollPane->IScrollPane(itsWindow, this, 10, 10, 0, 0,
  299.                                sizELASTIC, sizELASTIC, TRUE, TRUE, TRUE);
  300.  
  301.         /* The FitToEnclFrame() method makes the scroll pane be as large as
  302.         ** its enclosure.  In this case, the enclosure is the window, so the
  303.         ** scroll pane will take up the entire window.                        */
  304.  
  305.     theScrollPane->FitToEnclFrame(TRUE, TRUE);
  306.  
  307.  
  308.         /* itsMainPane is the document's focus of attention. Some of the standard
  309.         ** classes (particularly CPrinter) rel on itsMainPane pointing to the main
  310.         ** pane of your window.
  311.         **
  312.         ** itsGopher specifies which object should become the gopher when the document
  313.         ** becomes active. By default the document becomes the gopher. It╒s likely
  314.         ** that your main pane handles commands so you╒ll almost always want to set
  315.         ** itsGopher to point to the same object as itsMainPane.
  316.         **
  317.         ** Note that the main pane is the panorama in the scroll pane and not
  318.         ** the scroll pane itself.                                                    */
  319.  
  320.     theMainPane = new(CStarterPane);
  321.     theMainPane->IStarterPane(
  322.                               theScrollPane,    /* CView        */
  323.                               this,                /* CBureaucreat */
  324.                               0,                /* aWidth        */
  325.                               0,                /* aHeight        */
  326.                               0,                /* aHEncl        */
  327.                               0,                /* aVEncl        */
  328.                               sizELASTIC,        /* aHSizing        */
  329.                               sizELASTIC        /* aVSizing        */
  330.                              );
  331.     itsMainPane = theMainPane;
  332.     itsGopher = theMainPane;
  333.     
  334.         /* The FitToEnclosure() method makes the pane fit inside the enclosure.
  335.         ** The inside (or interior) of a scroll pane is defined as
  336.         ** the area inside the scroll bars.                                        */
  337.  
  338.     theMainPane->FitToEnclosure(TRUE, TRUE);
  339.  
  340.         /* Send the scroll pane an InstallPanorama() message to associate
  341.         ** the panorama with the scroll pane.                                */
  342.  
  343.     theScrollPane->InstallPanorama(theMainPane);
  344.     
  345.         /* The Decorator is a global object that takes care of placing and
  346.         ** sizing windows on the screen.  You don't have to use it.            */
  347.  
  348.     gDecorator->PlaceNewWindow(itsWindow);
  349.     
  350. }    /* BuildWindow */
  351.  
  352.  
  353.  
  354. /* DoSave
  355. **
  356. **        This method handles what happens when the user chooses Save from the
  357. **        File menu. This method should return TRUE if the file save was successful.
  358. **        If there is no file associated with the document, you should send a
  359. **        DoSaveFileAs() message.
  360. */
  361.  
  362. Boolean        CStarterDoc::DoSave (void)        {
  363.  
  364.         /* If you closed your file in your NewFile() method,
  365.         ** you'll need a different way than this to determine
  366.         ** if there's a file associated with your document.    */
  367.  
  368.     if (itsFile == NULL)
  369.         return(DoSaveFileAs());
  370.     else {
  371.             
  372.         /* In your application, this is where you'd write
  373.         ** out your file. if you left it open, send the
  374.         ** WriteSome() or WriteAll() mesages to itsFile.    */
  375.             
  376.         dirty = FALSE;                    /* Document is no longer dirty        */
  377.         gBartender->DisableCmd(cmdSave);
  378.         return(TRUE);                    /* Save was successful                */
  379.     }
  380.     
  381. }    /* DoSave */
  382.  
  383.  
  384.  
  385. /* DoSaveAs
  386. **
  387. **        This method handles what happens when the user chooses Save As╔ from
  388. **        File menu. The default DoCommand() method for documents sends a DoSaveFileAs()
  389. **        message which displays a standard put file dialog and sends this message.
  390. **        The SFReply record contains all the information about the file you're about
  391. **        to create.
  392. */
  393.  
  394. Boolean        CStarterDoc::DoSaveAs (SFReply *macSFReply)        {
  395.  
  396.         /* If there's a file associated with this document already, close it.
  397.         ** The Dispose() method for files sends a Close() message to the file
  398.         ** before releasing its memory.                                          */
  399.          
  400.     if (itsFile != NULL)
  401.         itsFile->Dispose();
  402.  
  403.         // Create a new file, and then save it normally:
  404.  
  405.     itsFile = new(CDataFile);
  406.     ((CDataFile *)itsFile)->IDataFile();
  407.     itsFile->SFSpecify(macSFReply);
  408.     itsFile->CreateNew(gSignature, 'TEXT');
  409.     itsFile->Open(fsRdWrPerm);
  410.     
  411.     itsWindow->SetTitle(macSFReply->fName);
  412.  
  413.     return( DoSave() );
  414.     
  415. }    /* DoSaveAs */
  416.  
  417.  
  418.  
  419. /* DoRevert
  420. **
  421. **        If your application supports the Revert command, this method
  422. **        should close the current file (without writing anything out)
  423. **        and read the last saved version of the file.
  424. */
  425.  
  426. void    CStarterDoc::DoRevert (void)    {
  427.  
  428. }    /* DoRevert */
  429.  
  430.  
  431.  
  432.  
  433. /* end: "CmyDoc.c" */